package org.tgcloud.group.service.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.tgcloud.group.core.*;
import org.tgcloud.group.core.WXUtils.WeiConfig;
import org.tgcloud.group.core.WXUtils.wxpay.WXDecodeDataUtil;
import org.tgcloud.group.core.session.Session;
import org.tgcloud.group.core.session.SessionFactory;
import org.tgcloud.group.entity.LogInfo;
import org.tgcloud.group.entity.MjNormalUser;
import org.tgcloud.group.entity.SysLabelValue;
import org.tgcloud.group.repository.LogInfoMapper;
import org.tgcloud.group.repository.MjNormalUserMapper;
import org.tgcloud.group.repository.SysLabelValueMapper;
import org.tgcloud.group.web.controller.dto.user.LoginUserDTO;
import org.tgcloud.group.web.controller.dto.user.UserAppDTO;
import org.tgcloud.group.web.controller.req.LoginAppReq;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static org.tgcloud.group.core.BaseLogger.printErrorInfo;

/**
 * @author: zhy
 * @create: 2023-08-14 15:43
 * @description:
 */
@Service
public class LoginService {

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private HttpClientUtil clientUtil;

    @Autowired
    private WeiConfig weiConfig;

    @Autowired
    private LogInfoMapper logInfoMapper;

    @Autowired
    private MjNormalUserMapper userMapper;

    @Autowired
    private SysLabelValueMapper sysLabelValueMapper;


    public APPResultMessage doLogin(APPResultMessage message, MjNormalUser user, String device_id, short device_type) {
        LoginUserDTO dto = new LoginUserDTO();
        dto.setHeadPic(user.getHeadPic());
        dto.setNickName(user.getNickName());
        dto.setTelephone(user.getTelephone());
        dto.setUserType(user.getUserType() == 4 ? (short) 2 : user.getUserType());
        dto.setUserId(user.getId());
        dto.setTouristType(user.getTouristType() == null ? (short) 1 : user.getTouristType());
        dto.setIsSubscribeMessage(user.getIsSubscribeMessage());
        dto.setIsShowAll(user.getUserType() == 4 ? (short) 2 : (user.getIsShowAll() == null ? (short) 1 : user.getIsShowAll()));
        dto.setIsAssistant(user.getIsAssistant());
        LogInfo info = logInfoMapper.selectSuccessLoginInfo(user.getId(), GlobalStatic.LOGIN_SUCCESS, (short) 1);
        if (info != null) {
            if (info.getDeviceId().equals(device_id)) {
                if (sessionFactory.getSession(info.getToken()) != null) {
                    message = APPResultMessage.getSuccessMessage();
                    message.setResult(ResultMessage.builder().setToken(info.getToken()).setData(dto));
                    return message;
                }
            }
        }
        Session session = sessionFactory.createSession(user.getId(), GlobalStatic.normal_user, device_id, null, null, null);
        message.setResult(ResultMessage.builder().setToken(session.getId().toString()).setData(dto));
        logInfoMapper.insert(new LogInfo(user.getId(), message.getResult().getToken(), device_id, device_type, GlobalStatic.normal_user));
        if (info != null) {
            info.setStatus(GlobalStatic.LOGIN_NO);
            logInfoMapper.updateByPrimaryKey(info);
            /*过期之前的session*/
            sessionFactory.destroySession(info.getToken());
            /*推送信息至之前的移动端：强制退出*/
        }
        return message;
    }



    public APPResultMessage<LoginUserDTO, List> doAppLogin(LoginAppReq req) {
        String key = "doLogin_" + req.getDeviceId();
        String requestId = UUID.randomUUID().toString();
        boolean flag = LockUtil.tryGetDistributedLock(key, requestId);
        if (flag) {
            try {
                String code = req.getCode();
                String deviceId = req.getDeviceId();
                String encryptedData = req.getEncryptedData();
                String iv = req.getIv();
                // 获取session_key
                String appId = WeiConfig.appId;
                String appSecret = WeiConfig.app_secret;
                String msg = clientUtil.doGet("https://api.weixin.qq.com/sns/jscode2session?appid=" + appId + "&secret=" + appSecret + "&js_code=" + code + "&grant_type=authorization_code", (Map) null);
                Map info = JSON.parseObject(msg, new TypeReference<Map>() {
                });
                if (StringUtil.isBlank(msg) || info == null) {
                    return new APPResultMessage(2233, "微信授权失败");
                } else {
                    System.out.println("获取信息===》" + msg);
                    String openid = (String) info.get("openid");
                    if (StringUtil.isBlank(openid)) {
                        return new APPResultMessage(2233, "openid获取失败");
                    }
                    String sessionKey = (String) info.get("session_key");
                    JSONObject phoneInfoJsonObject = WXDecodeDataUtil.getUserInfo(encryptedData, sessionKey, iv);
                    if (phoneInfoJsonObject == null) {
                        return new APPResultMessage(2233, "微信授权信息解密失败");
                    }
                    System.out.println("个人信息===》" + phoneInfoJsonObject);
                    //没有绑定公众号，无unionid
//                    String unionId = (String) info.get("unionid");
//                    if (StringUtil.isBlank(unionId)) {
//                        return new APPResultMessage(2233, "unionid获取失败");
//                    }

                    String purePhoneNumber = (String) phoneInfoJsonObject.get("purePhoneNumber");
                    UserAppDTO userAPPDTO = userMapper.selectMsgByTel(purePhoneNumber);
                    MjNormalUser user = new MjNormalUser();
                    boolean hasUserLogin = true;
                    if (null == userAPPDTO) {
                        //没有登录过的账户
//                        user.setCreateTime(new Date());
//                        user.setNickName(purePhoneNumber);
//                        user.setAppOpenId(openid);
//                        user.setStatus((short) 1);
//                        user.setTelephone(purePhoneNumber);
//                        user.setUserType((short) 1);
//                        userMapper.insertSelective(user);
                        hasUserLogin = false;
                    } else {
                        //登陆过的账户
                        if (StringUtil.isBlank(userAPPDTO.getNickName())){
                            user.setNickName(purePhoneNumber);
                        }
                        user.setTelephone(purePhoneNumber);
                        user.setAppOpenId(openid);
                        user.setId(userAPPDTO.getId());
                        user.setLastLoginTime(new Date());
                        userMapper.updateByPrimaryKeySelective(user);
                        user.setUserType(userAPPDTO.getUserType());
                        user.setNickName(userAPPDTO.getNickName());
                        user.setIsSubscribeMessage(userAPPDTO.getIsSubscribeMessage());
                        user.setTouristType(userAPPDTO.getTouristType());
                        user.setIsAssistant(userAPPDTO.getIsAssistant());
                    }
                    String s = sysLabelValueMapper.selectValueBySysIdAndReadOne(40);
                    if (StringUtil.isNotBlank(s) && "2".equals(s)){
                        SysLabelValue sysLabelValue = sysLabelValueMapper.selectValueBySysIdAndName(41, purePhoneNumber);
                        if (null != sysLabelValue){
                            MjNormalUser mjNormalUser = userMapper.selectByPrimaryKey(Integer.valueOf(sysLabelValue.getDesc()));
                            if (null != mjNormalUser){
                                user = mjNormalUser;
                                hasUserLogin = true;
                            }
                        }
                    }
                    if (!hasUserLogin){
                        return new APPResultMessage<>(7000, "该手机号没有登录权限");
                    }
                    return doLogin(APPResultMessage.getSuccessMessage(), user, req.getDeviceId(), (short) 1);
                }
            } catch (Exception e) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                printErrorInfo(e);
                APPResultMessage message = APPResultMessage.SYSTEM_ERROR();
                return message;
            } finally {
                LockUtil.releaseDistributedLock(key, requestId);
            }
        } else {
            return APPResultMessage.SYSTEM_BUSY();
        }

    }


    public APPResultMessage<LoginUserDTO, List> appLoginTest() {
        MjNormalUser user = userMapper.selectByPrimaryKey(9);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }



    public APPResultMessage<LoginUserDTO, List> appLoginTest2() {
        MjNormalUser user = userMapper.selectByPrimaryKey(10);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }

    public APPResultMessage<LoginUserDTO, List> appLoginTest3() {
        MjNormalUser user = userMapper.selectByPrimaryKey(17);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }

    public APPResultMessage<LoginUserDTO, List> appLoginTest4() {
        MjNormalUser user = userMapper.selectByPrimaryKey(43);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }

    public APPResultMessage<LoginUserDTO, List> appLoginTest5() {
        MjNormalUser user = userMapper.selectByPrimaryKey(42);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }


    public APPResultMessage<LoginUserDTO, List> appLoginTestNew(Integer testUserId) {
        MjNormalUser user = userMapper.selectByPrimaryKey(testUserId);
        return doLogin(APPResultMessage.getSuccessMessage(), user, "1", (short) 1);
    }
}
